<template>
  <div>
    <MSearchMax v-if="renderData?.search && renderData?.search?.length > 0" ref="search" :search="searchList" @doSearch="doSearch" />
    <MTablePlus ref="table" v-bind="renderData.vxeTableProps"
                :mergeCells="renderData?.mergeCells"
                :columns="columns"
                :show-page="hasPaging"
                :btn-list="[...showLeftBtnList, ...showRightBtnList]"
                @initData="initData">
      <template v-for="item in allSolts" #[item.slot??item.header]="scope">
        <a v-if="item.type === 'button'" v-bind="item" :key="item.key" v-has="item.permission" :class="{ 'light-red': item.type === 'error' && !item.disabled() }" @click="soltBtnClick({ row: scope.row, selected, refresh }, item.callback)">{{ scope.row[item.key] }}</a>
        <slot v-if="item.slot" :name="item.slot" v-bind="{ row: scope.row, refresh, index: scope.index }" />
        <slot v-if="item.header" :name="item.header" v-bind="{ row: scope.row }" />
      </template>
      <template v-for="item in allExpand" #[item.expand]="scope">
        <slot v-if="item.expand" :name="item.expand" v-bind="{ row: { ...scope.row, refresh } }"></slot>
      </template>
      <!-- <slot v-if="item.expand" :name="item.expand" v-bind="{ row: scope.row }"></slot> -->
      <template v-if="lineBtnList.length > 0" #lineOperation="{ row, index }">
        <span v-for="(btn, lineIndex) in lineBtnList.filter(t => !getBtnHide(t.hide, row)).slice(0, lineBtnMax)" :key="`button_${btn.label}_${index}`">
          <!-- v-if="!getBtnHide(btn.hide, row)" -->
          <a v-has="btn.permission" v-bind="btn" :class="{ 'light-red': btn.type === 'error' && !getDisabled(btn.disabled, row) }" :disabled="getDisabled(btn.disabled, row)" @click="linBtnClick({ row, selected, refresh }, btn.callback)">{{ pretty(btn.label, row) }}</a>
          <Divider v-if="lineIndex !== lineBtnList.filter(t => !getBtnHide(t.hide, row)).slice(0, lineBtnMax).length - 1" type="vertical" />
        </span>
        <template v-if="lineBtnList.filter(t => !getBtnHide(t.hide, row)).length > lineBtnMax">
          <Divider type="vertical" />
          <Poptip :ref="`poptip__${index}`" placement="bottom-end" transfer trigger="click">
            <a>更多</a>
            <template #content>
              <div class="op-more">
                <a
                  v-for="btn in lineBtnList.filter(t => !getBtnHide(t.hide, row)).slice(lineBtnMax, lineBtnList.filter(t => !getBtnHide(t.hide, row)).length)"
                  :key="pretty(btn.label, row)"
                  v-has="btn.permission"
                  v-bind="btn"
                  :class="{ 'light-red': btn.type === 'error' && !getDisabled(btn.disabled, row) }"
                  :disabled="getDisabled(btn.disabled, row)"
                  @click="moreLineBtnClick({ row, selected, refresh }, index, btn.callback)"
                >
                  {{ pretty(btn.label, row) }}
                </a>
              </div>
            </template>
          </Poptip>
        </template>
      </template>
      <template v-if="leftBtnList.length > leftBtnMax" #btn>
        <Dropdown transfer @on-click="leftMoreClick">
          <Button>
            更多操作
            <Icon
              type="md-arrow-dropdown"
              size="18"
            />
          </Button>
          <template #list>
            <Dropdown-menu>
              <Dropdown-item v-for="btn in leftBtnMore" :key="btn.label" :name="btn.name">
                {{ pretty(btn.label, {})}}
              </Dropdown-item>
            </Dropdown-menu>
          </template>
        </Dropdown>
      </template>
      <template #right>
        <slot name="right" />
      </template>
    </MTablePlus>
  </div>
</template>

<script>
import { cloneDeep } from 'lodash'
import MTablePlus from '@/components/m-table-plus/index.vue'

// import  MSearchPlus from '@/components/m-search-plus/index.vue'
import { typeOf } from '@/shared/Observer'
import { MModal } from '@/components/m-modal/index'
import MSearchMax from '@/components/m-search-max/index.vue'

export default {
  name: 'MSearchTable',
  components: {
    MTablePlus,
    // MSearchPlus,
    MSearchMax
  },
  props: {
    renderData: {
      required: true,
      type: Object
    },
    value: []
  },
  data () {
    return {
      lineBtnLongestLength: 0,
      isMorelineBtn: false,
      searchData: Object.create(null)
    }
  },
  computed: {
    hasPaging () {
      return this.renderData.hasPaging !== false
    },
    allSolts () {
      return this.renderData.table.filter(t => !!t.slot || !!t.header)
    },
    allExpand () {
      return this.renderData.table.filter(t => t.expand)
    },
    lineBtnMax () {
      return this.renderData.lineOperation?.lineBtnMax || 3
    },
    lineBtnList () {
      let list
      if (Array.isArray(this.renderData.lineOperation)) { list = this.renderData.lineOperation } else { list = this.renderData.lineOperation?.btnList || [] }
      return list
    },
    lineBtnWidth () {
      if (this.renderData.lineOperation?.lineBtnWidth) { return this.renderData.lineOperation.lineBtnWidth }
      const length = this.lineBtnLongestLength
      const width = length * 7 + (this.lineBtnMax - 1) * 12 + 28 // 计算宽度
      if (this.isMorelineBtn) { return width + 13 * 2 + 12 + 5 }
      return width
    },
    columns () {
      if (this.lineBtnList.length > 0) {
        // 算width
        return [...this.renderData.table,
          {
            title: '操作',
            slot: 'lineOperation',
            fixed: 'right',
            width: this.lineBtnWidth
          }
        ]
      } else {
        return this.renderData.table
      }
    },
    selected () {
      return this.$refs.table.getSelection()
    },
    leftBtnMax () {
      return this.renderData.operation?.leftMax || 4
    },
    rightBtnMax () {
      return this.renderData.operation?.rightMax || 4
    },
    btnList () {
      let list
      if (Array.isArray(this.renderData.operation)) { list = this.renderData.operation } else { list = this.renderData.operation?.btnList || [] }
      return list.map((t) => {
        const obj = { label: 'name', callback: 'func' }
        Object.keys(obj).forEach((k) => {
          t[obj[k]] = t[k]
        })
        return t
      })
    },
    leftBtnList () {
      return this.btnList.filter(t => t.float !== 'right').map(v => Object.assign(v, { searchData: this.searchData }))
    },
    rigthBtnList () {
      return this.btnList.filter(t => t.float === 'right').map(v => Object.assign(v, { searchData: this.searchData }))
    },
    showLeftBtnList () {
      return this.leftBtnList.slice(0, this.leftBtnMax)
    },
    showRightBtnList () {
      // 延后开发 右边更多
      return this.rigthBtnList
      // return this.rigthBtnList.slice(0, this.rightBtnMax)
    },
    leftBtnMore () {
      return this.leftBtnList.slice(this.leftBtnMax, this.leftBtnList.length).map(v => Object.assign(v, { searchData: this.searchData }))
    },
    searchList () {
      return this.renderData.search || []
    },
    refresh () {
      return this.$refs.table.refresh
    }

  },
  methods: {
    getSearchData () {
      return this.$refs.search.getSearchData()
    },
    async soltBtnClick (others, callback) {
      const res = await callback(others)
      if (typeOf(res, 'object') && res.render) { MModal(res) }
    },
    pretty (data, others) {
      if (typeof data === 'function') return data(others)
      return data
    },
    doSearch (params) {
      // 处理search里面的callback
      this.searchList.forEach((item) => {
        if (item.callback && typeof item.callback === 'function') {
          const obj = item.callback(params[item.key], params)
          delete params[item.key]
          params = { ...obj, ...params }
        }
      })
      this.$refs.table.handleSearch(params)
    },
    async initData (param, callback) {
      let qSearch = {}

      if (this.searchList && this.searchList.length !== 0) { qSearch = this.$refs.search.getSearchData() }

      this.searchList.forEach((item) => {
        if (item.callback && typeof item.callback === 'function') {
          const obj = item.callback(qSearch[item.key], param)
          delete qSearch[item.key]
          qSearch = { ...qSearch, ...obj }
        }
      })
      const sub = this.renderData.api.subParams ? this.renderData.api.subParams : {}
      let params = {
        ...param,
        ...sub,
        ...qSearch
      }
      params = Object.keys(params).reduce((obj, key) => {
        if (!['', null, undefined].includes(params[key])) { obj[key] = params[key] }
        return obj
      }, {})
      this.searchData = Object.assign(params, params)
      try {
        let res = await this.renderData.api.exec(params)
        if (this.renderData.api.responseFomate) { res = this.renderData.api.responseFomate(res) }
        console.log(res, 'res6')
        if (res.success) {
          console.log(res, 'res1')
          if (res.data.total !== null && res.data.total !== undefined) {
            callback(res.data)
            this.getLongestLineWidth(res.data.records)
          } else {
            // eslint-disable-next-line node/no-callback-literal
            callback({ records: res.data })
            this.getLongestLineWidth(res.data)
          }
        } else {
          // eslint-disable-next-line node/no-callback-literal
          callback([])
          this.getLongestLineWidth(0)
        }
        this.renderData.api?.afterSearch?.(params, res)
      } catch (e) {
        // eslint-disable-next-line node/no-callback-literal
        callback([])
      }
      this.expandAllRowEvent()
    },
    leftMoreClick (e) {
      // eslint-disable-next-line no-undef
      this.leftBtnMore.find(t => t.label === e).callback({ selected: this.selected, refresh, searchData: cloneDeep(this.searchData) })
    },
    getDisabled (dis, row) {
      if (typeof dis === 'function') { return dis({ row }) }
      return dis
    },
    async linBtnClick (props, callback) {
      const res = await callback(props)
      if (typeOf(res, 'object')) { MModal(res) }
    },
    async moreLineBtnClick (props, index, callback) {
      const res = await callback(props)
      if (typeOf(res, 'object')) { MModal(res) }
      const ref = this.$refs[`poptip__${index}`]
      ref.cancel()
    },
    getStrLength (list) {
      // 获取字符长度  汉字2 数组字母1
      // eslint-disable-next-line no-return-assign
      return !list.length ? 0 : list.reduce((sum, item) => sum += item.charCodeAt() > 255 ? 2 : 1, 0)
    },
    getBtnHide (hide, row) {
      if (typeof hide === 'function') { return hide({ row }) }
      return !!hide
    },
    expandAllRowEvent () {
      return this.$refs.table.expandAllRowEvent()
    },
    getLongestLineWidth (data) {
      // 数据返回后计算编辑按钮最大宽度
      if (!data) { return 0 }
      const btnLengthList = data.map((item) => {
        const list = this.lineBtnList.filter(t => !this.getBtnHide(t.hide, item))
        const strList = list.slice(0, this.lineBtnMax).map(t => t.label).join('').split('')
        if (this.lineBtnList.filter(t => !this.getBtnHide(t.hide, item)).length > this.lineBtnMax) { this.isMorelineBtn = true }
        return this.getStrLength(strList)
      })
      this.lineBtnLongestLength = btnLengthList.sort((a, b) => b - a)[0]
    }
  }
}
</script>

<style scoped lang="less">
.light-red {
  color: var(--highlight-red);
}
.op-more {
    cursor: pointer;
    a{
        display: block;
        text-align: center;
        padding: 5px 0;
    }
}
:deep(.el-tag.el-tag--info){
    color:#515a6e;
    padding: 0 10px;
    margin: 2px 0px 2px 4px;
    border: 1px solid #e8eaec;
    background: #f7f7f7;
    vertical-align: middle;
    opacity: 1;
    font-size: 12px;
}
:deep(.vxe-body--column){
  min-height: 50px !important;
  &>div{
    max-height: none !important;
  }
}
</style>
